package com.ruoyi.service.impl;

import java.security.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.ruoyi.domain.Category;
import com.ruoyi.domain.dto.BookDto;
import com.ruoyi.mapper.CategoryMapper;
import com.ruoyi.mapper.DictDataMapper;
import com.ruoyi.pojo.dto.Dict;
import com.ruoyi.pojo.vo.*;
import com.ruoyi.service.IShelvedBookService;
import com.ruoyi.utils.DtoToEntityConverter;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.mapper.SysUserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.mapper.BookMapper;
import com.ruoyi.domain.Book;
import com.ruoyi.service.IBookService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 图书管理Service业务层处理
 *
 * @author qyb
 * @date 2023-12-26
 */
@Service
public class BookServiceImpl implements IBookService {
    @Autowired
    private BookMapper bookMapper;
    @Autowired
    private DictDataMapper dictDataMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public AjaxResult addBook(BookDto bookDto) {
        Book book = DtoToEntityConverter.convertDtoToEntity(bookDto, Book.class);
        int count = bookMapper.insert1Book(book);
        return (count != 0) ? AjaxResult.success("新增图书成功") : AjaxResult.error(201, "新增图书失败");
    }
    @Override
    @Transactional
    public AjaxResult deleteBook( String ids) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            JsonNode jsonNode = objectMapper.readTree(ids);
            // 提取bookIds数组
            JsonNode bookIdsNode = jsonNode.get("bookIds");
            int count=0;
            int deleteCount=0;
            ArrayList<Long> list = new ArrayList<>();
            if (bookIdsNode != null && bookIdsNode.isArray()) {
                for (JsonNode idNode : bookIdsNode) {
                    String bookId = idNode.asText();
                    count++;
                    list.add(Long.valueOf(bookId));
                }
            } else {
                throw new RuntimeException("Invalid JSON format");
            }
            for (long id:list
            ) {
                bookMapper.deleteBook(id);
                deleteCount++;
            }
            if (count==deleteCount)
                return AjaxResult.success("删除成功"+","+"删除数量"+deleteCount+"条");
            else
                throw new RuntimeException("删除失败");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public AjaxResult updateBook(BookDto bookDto) {
        try {
            Book book = DtoToEntityConverter.convertDtoToEntity(bookDto, Book.class);
            int count = bookMapper.updateBook(book);
            return (count != 0) ? AjaxResult.success("更新成功") : AjaxResult.error(201, "更新失败");
        } catch (
                Exception e
        ) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<BookVo> searchBook(String searchByName,Integer pageSize,Integer pageNum) {
//        PageHelper.startPage(pageNum, pageSize);
        // 使用 JSON 解析库将 JSON 字符串转换为 Map 对象
        Map<String, String> paramMap = JSON.parseObject(searchByName, new TypeReference<Map<String, String>>() {
        });
        // 获取具体的搜索名字（假设是 "java"）
        String name = paramMap.get("searchByName");

        Integer offset=(pageNum - 1) * pageSize;
        List<Book> bookList = bookMapper.selectAllBooksPaged1(name, pageSize,offset);

        ArrayList<BookVo> bookVos = new ArrayList<>();
        if (bookList!=null){
            for (Book book:bookList
            ) {
                BookVo bookVo = new BookVo();
                int author = book.getAuthor();
                String author1 = bookMapper.author(author);
                int language = book.getLanguage();
                String language1 = bookMapper.language(language);
                int publish = book.getPublish();
                String publish1 = bookMapper.publish(publish);
                String createBy = book.getCreateBy();
                String updateBy = book.getUpdateBy();
                SysUser sysCreateUser = sysUserMapper.selectUserById(Long.valueOf(createBy));
                SysUser sysUpdateUser = sysUserMapper.selectUserById(Long.valueOf(updateBy));

                String categoryId = book.getCategoryId();
                String[] split = categoryId.split(",");
                ArrayList<String> categoryList = new ArrayList<>();
                for (String category:split
                ) {
                    categoryList.add(categoryMapper.name(Integer.parseInt(category)));
                }
                BeanUtils.copyProperties(book,bookVo);
                bookVo.setCreateBy(sysCreateUser.getUserName());
                bookVo.setUpdateBy(sysUpdateUser.getUserName());
                bookVo.setAuthor(author1);
                bookVo.setLanguage(language1);
                bookVo.setPublish(publish1);
                bookVos.add(bookVo);
                bookVo.setCategoryName(categoryList);
                bookVo.setAuthorValue(author);
                bookVo.setLanguageValue(language);
                bookVo.setPublishValue(publish);
                bookVo.setCategoryValue(Arrays.asList(split));
            }
            return bookVos;
        }
        else
            return null;

    }


    @Override
    public AjaxResult insertPublishAndLanguageDict(SysDictData sysDictData) throws ParseException {
        if (sysDictData.getDictType().equals("sys_book_publish")){
            List<SysDictData> sysBookPublish = dictDataMapper.selectDict("sys_book_publish");
            int size = sysBookPublish.size();
            SysDictData sysDictData1 = new SysDictData();
            sysDictData1.setDictSort((long) (size+1));
            sysDictData1.setDictLabel(sysDictData.getDictLabel());
            sysDictData1.setDictType("sys_book_publish");
            sysDictData1.setCreateBy("admin");
            // 定义日期时间格式
            String pattern = "yyyy-MM-dd HH:mm:ss";
            // 创建 SimpleDateFormat 实例
            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
            // 将字符串解析为 Date 对象
            Date date = dateFormat.parse("2023-12-28 15:26:19");
            sysDictData1.setCreateTime(date);
            sysDictData1.setStatus("0");
            int count = dictDataMapper.insertSysDictData(sysDictData1);
            return (count!=0)?AjaxResult.success("插入出版社字典成功"):AjaxResult.error(201,"插入出版社字典失败");
        }
        else {
            List<SysDictData> sysBookPublish = dictDataMapper.selectDict("sys_book_language");
            int size = sysBookPublish.size();
            SysDictData sysDictData1 = new SysDictData();
            sysDictData1.setDictSort((long) (size+1));
            sysDictData1.setDictLabel(sysDictData.getDictLabel());
            sysDictData1.setDictType("sys_book_language");
            sysDictData1.setCreateBy("admin");
            // 定义日期时间格式
            String pattern = "yyyy-MM-dd HH:mm:ss";
            // 创建 SimpleDateFormat 实例
            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
            // 将字符串解析为 Date 对象
            Date date = dateFormat.parse("2023-12-28 15:26:19");
            sysDictData1.setCreateTime(date);
            sysDictData1.setStatus("0");
            int count = dictDataMapper.insertSysDictData(sysDictData1);
            return (count!=0)?AjaxResult.success("插入语言字典成功"):AjaxResult.error(201,"插入语言字典失败");
        }
    }


    @Override
    public AjaxResult selectPublishAndLanguageDict(SysDictData sysDictData) {
        if (sysDictData.getDictType().equals("sys_book_publish")){
            List<SysDictData> sysBookPublish = dictDataMapper.selectDict("sys_book_publish");
            return (sysBookPublish!=null)? AjaxResult.success("出版社字典加载成功",sysBookPublish):AjaxResult.error("出版社字典加载失败");
        }
        else {
            List<SysDictData> sysBookLanguage = dictDataMapper.selectDict("sys_book_language");
            return (sysBookLanguage!=null)? AjaxResult.success("语言字典加载成功",sysBookLanguage):AjaxResult.error("语言字典加载失败");
        }
    }

    @Override
    public AjaxResult selectBookAuthor(String type) {
//        JSONObject jsonObject = JSONObject.parseObject(type);
//        String s= (String) jsonObject.get("type");
//        System.out.println(s);

        Map maps = (Map)JSON.parse(type);
        ArrayList<Object> list = new ArrayList<>();
        System.out.println("这个是用JSON类来解析JSON字符串!!!");
        for (Object map : maps.entrySet()){
            list.add( ((Map.Entry)map).getValue());
        }
        String o = (String)list.get(0);
        if (o.equals("author")){ //模糊
            List<BookAuthorVo> bookAuthorVos = bookMapper.selectBookAuthor();
            return AjaxResult.success(bookAuthorVos);
        }
        if (o.equals("username")){ //不要
            List<UserVO> userVOS = bookMapper.selectUserVo();
            return AjaxResult.success(userVOS);
        }
        if (o.equals("publish")) //模糊
        {
            List<BookPublishVo> bookPublishVos = bookMapper.selectBookPublish();
            return AjaxResult.success(bookPublishVos);
        }
        if (o.equals("category")){  //保留
            List<Category> categoryList = categoryMapper.selectCategoryDict();
            return AjaxResult.success(categoryList);
        }
        else {  //保留
            List<BookLanguageVo> bookLanguageVos = bookMapper.selectBookLanguage();
            return AjaxResult.success(bookLanguageVos);
        }
    }

    @Override
    public synchronized AjaxResult addBookAuthor(String data) throws ParseException, JsonProcessingException {
// 定义日期时间格式
        String pattern = "yyyy-MM-dd HH:mm:ss";

// 创建 SimpleDateFormat 实例
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);

// 格式化当前时间
        String formattedDate = dateFormat.format(new Date());

        System.out.println("Formatted Date: " + formattedDate);
        // 将格式化后的日期时间字符串解析为 Date 对象
        Date date = dateFormat.parse(formattedDate);
        JSONObject jsonObject = JSONObject.parseObject(data);
        String ty = jsonObject.getString("type");
        String value = jsonObject.getString("value");
        String[] values = value.split("@");
        String[] categoryValues = value.split(",");
        if (ty.equals("author")){
            List<BookAuthorVo> bookAuthorVos = bookMapper.selectBookAuthor();
            int size = bookAuthorVos.size();
            for (String s:values
            ) {
//                String chineseCharacters = retainChineseCharacters(s);
//                s = s.replace("[", "").replace("]", "").replace("\"","");
                int startIndex = s.indexOf("[") + 1; // 找到左边第一个 [ 的索引位置
                int endIndex = s.lastIndexOf("]");   // 找到右边第一个 ] 的索引位置
                String result = s.substring(startIndex, endIndex);
                s = result.replace("\"","");
                bookMapper.addBookAuthor(s, size, date);
                size++;
            }
            return AjaxResult.success(size-1);
        }
        if (ty.equals("publish")){
            List<BookPublishVo> bookAuthorVos = bookMapper.selectBookPublish();
            int size = bookAuthorVos.size();
            for (String s:values
            ) {
//                String chineseCharacters = retainChineseCharacters(s);
                s = s.replace("[", "").replace("]", "").replace("\"","");

                bookMapper.addBookPublish(s, size, date);
                size++;
            }
            return AjaxResult.success(size-1);
        }
        if (ty.equals("language")){
            List<BookLanguageVo> bookAuthorVos = bookMapper.selectBookLanguage();
            int size = bookAuthorVos.size();
            for (String s:values
            ) {
//                String chineseCharacters = retainChineseCharacters(s);
                s = s.replace("[", "").replace("]", "").replace("\"","");

                bookMapper.addBookLanguage(s, size, date);
                size++;
            }
            return AjaxResult.success(size-1);
        }
        else {
            List<Category> bookAuthorVos = categoryMapper.selectCategory();
            int size = bookAuthorVos.size();
            ArrayList<Object> list = new ArrayList<>();
            for (String s:categoryValues
            ) {
                String chineseCharacters = retainChineseCharacters(s);
                Category category = new Category();
                category.setName(chineseCharacters);
                category.setValue(size);
                category.setCreateTime(date);
                categoryMapper.addCategory(category);
                list.add(size);
                size++;
            }
            return AjaxResult.success(list);
        }

//        JSONObject jsonObject = JSONObject.parseObject(data);
//        String author= (String) jsonObject.getString("author");
//        String publish= (String) jsonObject.getString("publish");
//        String language= (String) jsonObject.getString("language");
//        String category= (String) jsonObject.getString("category");

//        int count=0;
//        if (author!=null){
//            String type="author";
//            ArrayList<?> list = getList("data", author);
//            for (Object i:list
//                 ) {
//                bookMapper.addBookAuthor((String) i, date);
//                count++;
//            }
//            return (count!=0) ?AjaxResult.success("添加成功"):AjaxResult.error("添加失败");
//        }
//        if (publish.equals("publish"))
//        {
////            int count = bookMapper.addBookPublish(s, date);
//            count++;
//            return (count!=0) ?AjaxResult.success("添加成功"):AjaxResult.error("添加失败");
//        }
//        if (category.equals("category")){
////            int count = bookMapper.addBookLanguage(s, date);
//            return (count!=0) ?AjaxResult.success("添加成功"):AjaxResult.error("添加失败");
//        }
//        else {
////            int count = bookMapper.addBookLanguage(s, date);
//            return (count!=0) ?AjaxResult.success("添加成功"):AjaxResult.error("添加失败");
//        }
    }

    @Override
    public AjaxResult selectBookById(int id) {
        Book book = bookMapper.selectBookByBookId((long) id);
        BookVo bookVo = new BookVo();
        BeanUtils.copyProperties(book,bookVo);
        bookVo.setAuthor(bookMapper.author(book.getAuthor()));
        bookVo.setLanguage(bookMapper.language(book.getLanguage()));
        bookVo.setPublish(bookMapper.publish(book.getPublish()));
        SysUser sysCreateUser = sysUserMapper.selectUserById(Long.valueOf(book.getCreateBy()));
        SysUser sysUpdateUser = sysUserMapper.selectUserById(Long.valueOf(book.getUpdateBy()));
        String categoryId = book.getCategoryId();
        String[] split = categoryId.split(",");
        ArrayList<String> categoryList = new ArrayList<>();
        for (String category:split
        ) {
            categoryList.add(categoryMapper.name(Integer.parseInt(category)));
        }
        bookVo.setCreateBy(sysCreateUser.getUserName());
        bookVo.setUpdateBy(sysUpdateUser.getUserName());
        bookVo.setCategoryName(categoryList);
        bookVo.setAuthorValue(book.getAuthor());
        bookVo.setLanguageValue(book.getLanguage());
        bookVo.setPublishValue(book.getPublish());
        bookVo.setCategoryValue(Arrays.asList(split));
        return AjaxResult.success(bookVo);
    }

    @Override
    public AjaxResult selectAuthorAndPublishDict(Dict dict) {
        String type = dict.getType();
        if (type.equals("author")){
            List<BookAuthorVo> bookAuthorVos = bookMapper.selectBookAuthorMOhu(dict.getKeyWord());
            return AjaxResult.success(bookAuthorVos);
        }
        else if (type.equals("language")){
            List<BookLanguageVo> bookLanguageVos = bookMapper.selectBookLanguageMOhu(dict.getKeyWord());
            return AjaxResult.success(bookLanguageVos);
        }
        else {
            List<BookPublishVo> bookPublishVos = bookMapper.selectBookPublishMOhu(dict.getKeyWord());
            return AjaxResult.success(bookPublishVos);
        }
    }

    private static String retainChineseCharacters(String input) {
        // 使用正则表达式匹配汉字
        Pattern pattern = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher matcher = pattern.matcher(input);

        // 使用 StringBuilder 存储匹配到的汉字
        StringBuilder resultBuilder = new StringBuilder();
        while (matcher.find()) {
            resultBuilder.append(matcher.group());
        }

        return resultBuilder.toString();
    }
    private ArrayList<?> getList(String data,String type) throws JsonProcessingException {

//        ArrayList arrayList = JSONObject.parseObject("type", ArrayList.class);
//        return arrayList;
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(data);
        // 提取bookIds数组
        JsonNode bookIdsNode = jsonNode.get(type);
        int count=0;
        int deleteCount=0;
        ArrayList<Long> list = new ArrayList<>();
        if (bookIdsNode != null && bookIdsNode.isArray()) {
            for (JsonNode idNode : bookIdsNode) {
                String bookId = idNode.asText();
                count++;
                list.add(Long.valueOf(bookId));
            }
            return list;
        } else {
            throw new RuntimeException("Invalid JSON format");
        }
    }


    /**
     * 统计查询模块：柱状图展现每一个作者对应的书的数量
     * @return
     */
    @Override
    public Map getAuthorBookNum() {
        Map<String, Integer> authorBookMap = new HashMap<>();
        //1.查出所有的作者，放到作者集合中
        List<String> authorList = bookMapper.getAllAuthor();
        for(String auth : authorList){
            //2.查出该作者对应的书的数量，放到map中
            Integer number = bookMapper.getAuthorBooks(auth);
            authorBookMap.put(auth,number);
        }
        return authorBookMap;
    }

    /**
     * 统计查询模块：饼状图展示每一种语言对应的书的数量
     * @return
     */
    @Override
    public Map<String, Integer> getLanguageNum() {
        Map<String, Integer> languageNumMap = new HashMap<>();
        //1.查出所有的语言
        List<String> languageList = bookMapper.getAllLanguage();
        for (String language : languageList){
            //2.查出该语言对应的书的数量
            Integer number = bookMapper.getLanguageNum(language);
            languageNumMap.put(language,number);
        }
        return languageNumMap;
    }

    @Override
    public int getTotal(String searchByName) {
        // 使用 JSON 解析库将 JSON 字符串转换为 Map 对象
        Map<String, String> paramMap = JSON.parseObject(searchByName, new TypeReference<Map<String, String>>() {
        });
        // 获取具体的搜索名字（假设是 "java"）
        String name = paramMap.get("searchByName");
        List<Book> bookList = bookMapper.selectAllBooksPaged(name);
        return bookList.size();
    }

    /**
     * 查询库存图书数量并且保存到数据库中去
     */
    @Override
    public void getBookNum(){
        //1.查询库存表中图书总的数量
        Integer bookNum= shelvedBookService.selectBookNum();
        //2.保存到图书数量变化表中去
        shelvedBookService.setBookNum(bookNum);
    }

    @Resource
    private IShelvedBookService shelvedBookService;
    /**
     * 每一天库存图书数量变化
     * @return
     */
    @Override
    public Map<String , Integer> getEveryDayBookNum() {
        HashMap<String, Integer> bookNumMap = new HashMap<>();
        //1.遍历表得到所有的日期
        List<LocalDate> day = bookMapper.getDay();
        System.out.println(day);
        for (LocalDate date: day) {
            //2.根据日期查询当天的库存数量
            Integer bookNum = bookMapper.getDayBookNum(date);
            String s = date.toString();
            //3.放到Map集合当中去
            bookNumMap.put(s, bookNum);
        }
        return bookNumMap;
    }
}
